package com.winit.openapi.ums.controller;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.Resource;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.winit.common.query.Page;
import com.winit.common.query.SearchOperator;
import com.winit.common.query.Searchable;
import com.winit.common.query.filter.SearchFilterHelper;
import com.winit.common.spi.context.CommandContext;
import com.winit.erp.spi.warehouse.WarehouseService;
import com.winit.erp.spi.warehouse.command.WarehouseCommand;
import com.winit.erp.spi.warehouse.vo.Warehouse;
import com.winit.openapi.constants.ApiConstant;
import com.winit.openapi.controller.BaseController;
import com.winit.openapi.model.RequestMsg;
import com.winit.openapi.model.ResponseMsg;
import com.winit.openapi.util.ValidateUtil;
import com.winit.pms.spi.winit.LogisticsdistService;
import com.winit.pms.spi.winit.WinitPostService;
import com.winit.pms.spi.winit.WinitProductItemService;
import com.winit.pms.spi.winit.WinitProductService;
import com.winit.pms.spi.winit.WinitSlaService;
import com.winit.pms.spi.winit.command.LogisticsDistFindCommand;
import com.winit.pms.spi.winit.command.SupplierListByProductAndCatalogCommand;
import com.winit.pms.spi.winit.command.WinitPostFindCommand;
import com.winit.pms.spi.winit.command.WinitProductQueryCommand;
import com.winit.pms.spi.winit.command.WinitSlaFindCommand;
import com.winit.pms.spi.winit.vo.LogisticsDist;
import com.winit.pms.spi.winit.vo.WinitPost;
import com.winit.pms.spi.winit.vo.WinitProduct;
import com.winit.pms.spi.winit.vo.WinitSla;
import com.winit.ums.spi.address.ReceiveAddressService;
import com.winit.ums.spi.address.command.QueryAddressCommand;
import com.winit.ums.spi.address.command.QueryAddressWarehouseCommand;
import com.winit.ums.spi.address.command.QueryWinitReceiveCommand;
import com.winit.ums.spi.address.vo.AddressWarehouseVo;
import com.winit.ums.spi.address.vo.ReceiveAddressVerifyVo;
import com.winit.ums.spi.address.command.QueryBoardAddressListCommand;
import com.winit.ums.spi.address.vo.ReceiveAddressVo;
import com.winit.ums.spi.address.vo.WarehouseVo;
import com.winit.ups.spi.basicdata.BasicDataService;
import com.winit.ups.spi.basicdata.command.GetBasicDataListCommand;
import com.winit.ups.spi.basicdata.vo.BasicData;

/**
 * 揽收地址Controller
 * 
 * @version <pre>
 * Author	Version		Date		Changes
 * kang.wang 	1.0  		2016年4月1日 	Created
 *
 * </pre>
 * @since 1.
 */
@Controller
@RequestMapping(value = "ums/receiveAddress")
public class ReceiveAddressController extends BaseController {

    @Resource
    private ReceiveAddressService   receiveAddressService;
    @Resource
    private WinitProductItemService winitProductItemService;
    @Resource
    private WinitSlaService         winitSlaService;
    @Resource
    private WinitPostService        winitPostService;
    @Resource
    private WarehouseService        warehouseService;
    @Resource
    private WinitProductService     winitProductService;
    @Resource
    private LogisticsdistService    logisticsdistService;
    
    @Resource
    private BasicDataService upsBasicDataService;
    
    private final Logger logger = LoggerFactory.getLogger(ReceiveAddressController.class);

    /**
     * 根据winitProductCode、dispatchType、serviceCatalog查询揽收地址列表
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/queryReceiveAddressList")
    public String queryReceiveAddressList(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        JSONObject json = (JSONObject) requestMsg.getData();
        ValidateUtil.validNotNull(json, "winitProductCode");
        ValidateUtil.validNotNull(json, "dispatchType");

        String productCode = json.getString("winitProductCode");
        String dispatchType = json.getString("dispatchType");
        String serviceCatalog = "Pickup";
        if(json.containsKey("serviceCatalog")){
            serviceCatalog = json.getString("serviceCatalog");
        }

        QueryAddressCommand command = new QueryAddressCommand();
        CommandContext ctx = CommandContext.getContext();
        command.setCtx(ctx);
        command.setUserId(Long.parseLong(ctx.getUserId()));
        command.setWinitProductLine(getWinitProductLine(productCode));
        // 查询提货服务地址
        if (ApiConstant.DISPATCH_TYPE_PICK_UP.equals(dispatchType)
                || ApiConstant.DISPATCH_TYPE_CHINAPOST.equals(dispatchType)) {
            SupplierListByProductAndCatalogCommand sc = new SupplierListByProductAndCatalogCommand();
            sc.setCtx(ctx);
            sc.setServiceCatalog(serviceCatalog);
            sc.setWinitProductCode(productCode);
            sc.setDispatchType(dispatchType);
            List<String> venderServiceCodeList = winitProductItemService.getSupplierCodeList(sc);
            command.setSupplierCode(venderServiceCodeList);
        }
        logger.info("调用UMS查询揽收地址，参数："+JSON.toJSONString(command));
        List<ReceiveAddressVo> receiveAddressVoList = receiveAddressService.queryReceiveAddress(command);
        logger.info("调用UMS查询揽收地址，出参："+JSON.toJSONString(receiveAddressVoList));
        Map<String, List<ReceiveAddressVo>> result = new HashMap<String, List<ReceiveAddressVo>>();
        result.put("list", receiveAddressVoList);
        responseMsg.setData(result);

        return SUCCESS;
    }
    
    /**
     * 根据winit揽收 燕文审核通过的地址
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/queryWinitReceiveAddressList")
    public String queryWinitReceiveAddressList(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        JSONObject json = (JSONObject) requestMsg.getData();
        ValidateUtil.validNotNull(json, "winitProductLine");
        String winitProductCode = json.getString("winitProductLine");
        if("P".equalsIgnoreCase(winitProductCode)){
            ValidateUtil.validNotNull(json, "supplierCode");
            ValidateUtil.validNotNull(json, "status");
        }

        QueryWinitReceiveCommand command = new QueryWinitReceiveCommand();
        command = JSON.parseObject(requestMsg.getData().toString(),QueryWinitReceiveCommand.class);
        CommandContext ctx = CommandContext.getContext();
        command.setCtx(ctx);
        command.setUserId(Long.parseLong(ctx.getUserId()));
        command.setWinitProductLine(winitProductCode);
        
        
        logger.info("调用UMS查询揽收地址，参数："+JSON.toJSONString(command));
        List<ReceiveAddressVerifyVo> receiveAddressVoList = receiveAddressService.queryWinitReceiveAddressList(command);
        logger.info("调用UMS查询揽收地址，出参："+JSON.toJSONString(receiveAddressVoList));
        Map<String, List<ReceiveAddressVerifyVo>> result = new HashMap<String, List<ReceiveAddressVerifyVo>>();
        result.put("list", receiveAddressVoList);
        responseMsg.setData(result);

        return SUCCESS;
    }
    
    
    
    /**
     * 根据winitProductCode、dispatchType、addressCode、serviceCatalog查询验货仓
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/queryReceiveWarehouseList")
    public String queryReceiveWarehouseList(@ModelAttribute RequestMsg requestMsg,
                                            @ModelAttribute ResponseMsg responseMsg) {
        JSONObject json = (JSONObject) requestMsg.getData();
        ValidateUtil.validNotNull(json, "winitProductCode");
        ValidateUtil.validNotNull(json, "dispatchType");
        ValidateUtil.validNotNull(json, "addressCode");
        ValidateUtil.validNotNull(json, "serviceCatalog");

        String productCode = json.getString("winitProductCode");
        String dispatchType = json.getString("dispatchType");
        String addressCode = json.getString("addressCode");
        String serviceCatalog = json.getString("serviceCatalog");

        // 查询提货服务地址验货仓
        if (ApiConstant.DISPATCH_TYPE_PICK_UP.equals(dispatchType)
                || ApiConstant.DISPATCH_TYPE_CHINAPOST.equals(dispatchType)
                || ApiConstant.DISPATCH_TYPE_DHL.equals(dispatchType)) {
            QueryAddressWarehouseCommand command = new QueryAddressWarehouseCommand();
            CommandContext ctx = CommandContext.getContext();
            command.setCtx(ctx);
            command.setUserId(Long.parseLong(ctx.getUserId()));
            command.setWinitProductLine(getWinitProductLine(productCode));
            command.setAddressCode(addressCode);
            SupplierListByProductAndCatalogCommand sc = new SupplierListByProductAndCatalogCommand();
            sc.setCtx(ctx);
            sc.setServiceCatalog(serviceCatalog);
            sc.setWinitProductCode(productCode);
            sc.setDispatchType(dispatchType);
            List<String> venderServiceCodeList = winitProductItemService.getSupplierCodeList(sc);
            command.setSupplierCode(venderServiceCodeList);
            logger.info("调用UMS查询揽收地址可用验货仓，参数："+JSON.toJSONString(command));
            AddressWarehouseVo addressWarehouseVo = receiveAddressService.queryReceiveWarehouseAndInspectionWarehouse(command);
            logger.info("调用UMS查询揽收地址可用验货仓，出参："+JSON.toJSONString(addressWarehouseVo));
            List<WarehouseVo> list = addressWarehouseVo.getInspectionWarehouse();

            List<WarehouseVo> rslist = new ArrayList<WarehouseVo>();

            if (list != null && !list.isEmpty()) {
                // 根据产品获取已配置的仓库邮编列表
                Set<String> postSet = getWarehousePostList(productCode);
                for (int i = 0; i < list.size(); i++) {
                    if (StringUtils.isNotBlank(list.get(i).getWarehouseCode())) {
                        WarehouseCommand warehouseCommand = new WarehouseCommand();
                        warehouseCommand.setValue(list.get(i).getWarehouseCode());
                        List<Warehouse> warehouses = warehouseService.getWarehouseList(warehouseCommand);
                        // 根据产品上配置的仓库过滤验货仓
                        if (warehouses != null && !warehouses.isEmpty()
                            && postSet.contains(warehouses.get(0).getPostal())) {
                            WarehouseVo customerWarehouse = list.get(i);
                            rslist.add(customerWarehouse);
                        }
                    }
                }
            }

            Map<String, List<WarehouseVo>> result = new HashMap<String, List<WarehouseVo>>();
            result.put("list", rslist);
            responseMsg.setData(result);
        }
        return SUCCESS;
    }

    /**
     * 获取Winit产品线
     * 
     * @param winitProductCode
     * @return
     */
    private String getWinitProductLine(String winitProductCode) {
        String productLine = null;
        WinitProductQueryCommand prodocutQComand = new WinitProductQueryCommand();
        prodocutQComand.setCode(winitProductCode);
        WinitProduct winitProduct = winitProductService.queryProduct(prodocutQComand);
        if (winitProduct != null) {
            productLine = winitProduct.getProductCatalogName();
        }
        return productLine;
    }

    /**
     * 获取仓库邮编列表
     * 
     * @param winitProductCode
     * @return
     */
    private Set<String> getWarehousePostList(String winitProductCode) {
        List<Long> logisticsIdList = new ArrayList<Long>();
        WinitProductQueryCommand prodocutQComand = new WinitProductQueryCommand();
        prodocutQComand.setCode(winitProductCode);
        WinitProduct winitProduct = winitProductService.queryProduct(prodocutQComand);
        if (winitProduct != null) {
            LogisticsDistFindCommand command = new LogisticsDistFindCommand();
            Searchable<?> searchable = Searchable.newSearchable();
            searchable.and(SearchFilterHelper.newCondition("DISTRICT_TYPE",
                SearchOperator.eq,
                ApiConstant.LOGISTIC_TYPE_WAREHOUSE));
            searchable.and(SearchFilterHelper.newCondition("WINIT_PRODUCT_ID",
                SearchOperator.eq,
                winitProduct.getWinitProductId()));
            // 查询所有的值
            searchable.setPage(0, Integer.MAX_VALUE);
            command.setSearchable(searchable);
            Page<LogisticsDist> page = logisticsdistService.findLogisticsDist(command);
            if (null != page && null != page.getContent() && page.getContent().size() > 0) {
                for (LogisticsDist logisticsDist : page.getContent()) {
                    if (isActiveWinitProductSla(winitProduct.getWinitProductId(),
                        logisticsDist.getWinitLogisticsdistId())) {
                        logisticsIdList.add(logisticsDist.getWinitLogisticsdistId());
                    }
                }
            }
        }
        return getPostal(logisticsIdList);
    }

    /**
     * 获取物流分区的邮编
     * 
     * @param logisticList
     * @return
     */
    private Set<String> getPostal(List<Long> logisticList) {
        Set<String> postSet = new HashSet<String>();
        if (CollectionUtils.isNotEmpty(logisticList)) {
            for (Long logisticId : logisticList) {
                WinitPostFindCommand command = new WinitPostFindCommand();
                Searchable<?> searchable = Searchable.newSearchable();
                searchable.and(SearchFilterHelper.newCondition("WINIT_LOGISTICSDIST_ID", SearchOperator.eq, logisticId));
                // 查询所有的值
                searchable.setPage(0, Integer.MAX_VALUE);
                command.setSearchable(searchable);
                Page<WinitPost> page = winitPostService.findWinitPost(command);
                if (null == page || null == page.getContent() || page.getContent().size() < 1) {
                    continue;
                }
                for (WinitPost post : page.getContent()) {
                    if (!postSet.contains(post.getCode())) {
                        postSet.add(post.getCode());
                    }
                }
            }
        }
        return postSet;
    }

    /**
     * 判断是否存在有效的SLA
     * 
     * @param winitProductId
     * @param logisticsDistId
     * @return
     */
    private boolean isActiveWinitProductSla(long winitProductId, long logisticsDistId) {
        WinitSlaFindCommand command = new WinitSlaFindCommand();
        Searchable<?> searchable = Searchable.newSearchable();
        Date date = new Date();
        searchable.and(SearchFilterHelper.newCondition("EFFECTIVE", SearchOperator.lt, date));
        searchable.and(SearchFilterHelper.newCondition("EXPIRY", SearchOperator.gt, date));
        searchable.and(SearchFilterHelper.newCondition("WINIT_PRODUCT_ID", SearchOperator.eq, winitProductId));
        searchable.and(SearchFilterHelper.newCondition("SLA_BEGIAN", SearchOperator.eq, logisticsDistId));
        // 查询所有的值
        searchable.setPage(0, Integer.MAX_VALUE);
        command.setSearchable(searchable);
        Page<WinitSla> page = winitSlaService.findWinitSla(command);
        if (null != page && null != page.getContent() && page.getContent().size() > 0) {
            return true;
        }
        return false;
    }
    
    
    /**
     * 根据winitProductCode，供应商编码 查询提柜地址列表
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/queryBoardAddressList")
    public String queryBoardAddressList(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        JSONObject json = (JSONObject) requestMsg.getData();
        
        List<String> venderServiceCodeList = new ArrayList<String>();
        GetBasicDataListCommand getBasicDataListCommand = new GetBasicDataListCommand();
        getBasicDataListCommand.setType("boardAddressSupplierCode");
        List<BasicData> list = upsBasicDataService.getBasicDataList(getBasicDataListCommand);
        for (int i = 0; i < list.size(); i++) {
        	venderServiceCodeList.add(list.get(i).getCode());
		}
        
        ValidateUtil.validNotNull(json, "winitProductLine");
        ValidateUtil.validNotNull(json, "warehouseCode");
        //产品线
        String winitProductLine = json.getString("winitProductLine");
        //仓库编码
        String warehouseCode = json.getString("warehouseCode");
        
        QueryBoardAddressListCommand command = new QueryBoardAddressListCommand();
        CommandContext ctx = CommandContext.getContext();
        command.setCtx(ctx);
        command.setUserId(Long.parseLong(ctx.getUserId()));
        command.setWinitProductLine(winitProductLine);
        command.setWarehouseCode(warehouseCode);
        command.setSupplierCode(venderServiceCodeList);
       
        logger.info("调用UMS查询提柜地址，参数："+JSON.toJSONString(command));
        List<ReceiveAddressVo> receiveAddressVoList = receiveAddressService.queryBoardAddressList(command);
        logger.info("调用UMS查询提柜地址，出参："+JSON.toJSONString(receiveAddressVoList));
        Map<String, Object> data = new HashMap<String, Object>();
        data.put("list", receiveAddressVoList);
        responseMsg.setData(data);
        return SUCCESS;
    }
}
